package com.example.demo.controller;

import com.example.demo.dao.UserDao;
import com.example.demo.entity.dto.TokenUserDto;
import com.example.demo.entity.pojo.User;
import com.example.demo.entity.vo.ResponseVO;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.UUID;
import java.util.regex.Pattern;

@RestController
@RequestMapping("/shezi")
public class SheZiController extends BaseController {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RedisTemplate redisTemplate;

    // 头像上传路径配置
    @Value("${app.upload.avatar.path:uploads/avatars/}")
    private String avatarUploadPath;

    /**
     * 获取头像存储目录路径
     * @return 头像存储目录的绝对路径
     */
    private String getAvatarStoragePath() {
        // 直接使用D盘的固定目录，方便前端访问
        String avatarDir = "D:/avatars/";
        return avatarDir;
    }

    /**
     * 修改密码接口
     *
     * @param request         HTTP请求对象，用于获取用户token
     * @param currentPassword 当前密码
     * @param newPassword     新密码
     * @return 响应结果
     */
    @PostMapping("/changePassword")
    public ResponseVO<String> changePassword(HttpServletRequest request,
                                             @RequestParam String currentPassword,
                                             @RequestParam String newPassword) {
        try {
            // 获取当前登录用户信息
            TokenUserDto tokenUserDto = getTokenUserDto(request);
            if (tokenUserDto == null) {
                return getFail("登录超时，请重新登录！");
            }

            // 参数验证
            if (StringUtils.isBlank(currentPassword) || StringUtils.isBlank(newPassword)) {
                return getFail("当前密码和新密码不能为空！");
            }

            if (newPassword.length() < 6) {
                return getFail("新密码长度不能少于6位！");
            }

            if (currentPassword.equals(newPassword)) {
                return getFail("新密码不能与当前密码相同！");
            }

            // 查询用户信息
            User user = userDao.queryById(tokenUserDto.getUserId());
            if (user == null) {
                return getFail("用户不存在！");
            }

            // 验证当前密码是否正确
            String encryptedCurrentPassword = DigestUtils.md5Hex(currentPassword);
            if (!encryptedCurrentPassword.equals(user.getPassword())) {
                return getFail("当前密码错误！");
            }

            // 加密新密码并更新
            String encryptedNewPassword = DigestUtils.md5Hex(newPassword);
            User updateUser = new User();
            updateUser.setUserId(user.getUserId());
            updateUser.setPassword(encryptedNewPassword);
            updateUser.setUpdatedAt(new Date());

            int result = userDao.update(updateUser);
            if (result > 0) {
                return getSuccess("密码修改成功！", null);
            } else {
                return getFail("密码修改失败，请稍后重试！");
            }

        } catch (Exception e) {
            return getFail("系统错误：" + e.getMessage());
        }
    }

    /**
     * 修改用户信息接口
     *
     * @param request  HTTP请求对象，用于获取用户token
     * @param username 新用户名（可选）
     * @param email    新邮箱（可选）
     * @param touXiang 头像文件（可选，支持jpg、jpeg、png、gif、bmp格式，最大5MB）
     * @return 响应结果
     */
    @PostMapping("/updateUserInfo")
    public ResponseVO<User> updateUserInfo(HttpServletRequest request,
                                           @RequestParam(required = false) String username,
                                           @RequestParam(required = false) String email,
                                           @RequestParam(required = false) MultipartFile touXiang) {
        try {
            // 获取当前登录用户信息
            TokenUserDto tokenUserDto = getTokenUserDto(request);
            if (tokenUserDto == null) {
                return getFail("登录超时，请重新登录！");
            }

            // 至少需要修改一个字段
            if (StringUtils.isBlank(username) && StringUtils.isBlank(email) && (touXiang == null || touXiang.isEmpty())) {
                return getFail("请至少提供一个要修改的字段！");
            }

            // 查询当前用户信息
            User currentUser = userDao.queryById(tokenUserDto.getUserId());
            if (currentUser == null) {
                return getFail("用户不存在！");
            }

            User updateUser = new User();
            updateUser.setUserId(currentUser.getUserId());
            updateUser.setUpdatedAt(new Date());

            // 验证并设置用户名
            if (StringUtils.isNotBlank(username)) {
                if (username.length() < 2 || username.length() > 20) {
                    return getFail("用户名长度必须在2-20个字符之间！");
                }
                updateUser.setUsername(username.trim());
            }

            // 验证并设置邮箱
            if (StringUtils.isNotBlank(email)) {
                email = email.trim();

                // 邮箱格式验证
                String emailRegex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
                if (!Pattern.matches(emailRegex, email)) {
                    return getFail("邮箱格式不正确！");
                }

                // 检查邮箱是否已被其他用户使用
                if (!email.equals(currentUser.getEmail())) {
                    User existingUser = userDao.queryByEmail(email);
                    if (existingUser != null && !existingUser.getUserId().equals(currentUser.getUserId())) {
                        return getFail("该邮箱已被其他用户使用！");
                    }
                }

                updateUser.setEmail(email);
            }

            // 处理头像上传
            if (touXiang != null && !touXiang.isEmpty()) {
                try {
                    // 验证文件类型
                    String originalFilename = touXiang.getOriginalFilename();
                    if (originalFilename == null || originalFilename.isEmpty()) {
                        return getFail("头像文件名不能为空！");
                    }

                    // 检查文件扩展名
                    if (!originalFilename.contains(".")) {
                        return getFail("头像文件必须有扩展名！");
                    }

                    String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
                    if (!fileExtension.matches("\\.(jpg|jpeg|png|gif|bmp)$")) {
                        return getFail("头像文件格式不支持，请上传jpg、jpeg、png、gif或bmp格式的图片！");
                    }

                    // 验证文件大小（限制为5MB）
                    if (touXiang.getSize() > 5 * 1024 * 1024) {
                        return getFail("头像文件大小不能超过5MB！");
                    }

                    // 获取头像存储目录
                    String uploadDir = getAvatarStoragePath();
                    File uploadDirFile = new File(uploadDir);
                    if (!uploadDirFile.exists()) {
                        boolean created = uploadDirFile.mkdirs();
                        if (!created) {
                            return getFail("无法创建头像存储目录！");
                        }
                    }

                    // 生成唯一文件名
                    String fileName = UUID.randomUUID().toString() + fileExtension;
                    String fullFilePath = uploadDir + fileName;

                    // 存储在数据库中的完整路径（前端可直接访问）
                    String dbFilePath = fullFilePath;

                    // 保存文件到本地应用数据目录
                    Path targetPath = Paths.get(fullFilePath);
                    Files.copy(touXiang.getInputStream(), targetPath);

                    // 删除旧头像文件（如果存在）
                    if (StringUtils.isNotBlank(currentUser.getTouXiang())) {
                        try {
                            File oldFile = new File(currentUser.getTouXiang());
                            if (oldFile.exists()) {
                                oldFile.delete();
                            }
                        } catch (Exception e) {
                            // 删除旧文件失败不影响主流程，只记录日志
                            System.err.println("删除旧头像文件失败: " + e.getMessage());
                        }
                    }

                    // 设置新头像路径（存储相对路径到数据库）
                    updateUser.setTouXiang(dbFilePath);

                } catch (IOException e) {
                    return getFail("头像上传失败：" + e.getMessage());
                }
            }

            // 执行更新
            int result = userDao.update(updateUser);
            if (result > 0) {
                // 返回更新后的用户信息
                User updatedUser = userDao.queryById(currentUser.getUserId());
                updatedUser.setPassword(null); // 不返回密码信息
                return getSuccess("用户信息修改成功！", updatedUser);
            } else {
                return getFail("用户信息修改失败，请稍后重试！");
            }

        } catch (Exception e) {
            return getFail("系统错误：" + e.getMessage());
        }
    }

    /**
     * 退出登录接口
     *
     * @param request HTTP请求对象，用于获取用户token
     * @return 响应结果
     */
    @PostMapping("/logout")
    public ResponseVO<String> logout(HttpServletRequest request) {
        try {
            // 获取token
            String authHeader = request.getHeader("authorization");
            if (StringUtils.isBlank(authHeader)) {
                return getFail("未找到登录信息！");
            }

            // 验证token格式 (Bearer token)
            if (!authHeader.startsWith("Bearer ")) {
                return getFail("Token格式错误！");
            }

            // 提取实际的token值
            String token = authHeader.substring(7);
            if (StringUtils.isBlank(token)) {
                return getFail("Token不能为空！");
            }

            // 检查token是否存在于Redis中
            String tokenKey = "token:" + token;
            Object tokenData = redisTemplate.opsForValue().get(tokenKey);

            if (tokenData == null) {
                return getFail("登录信息已过期或无效！");
            }

            // 从Redis中删除token
            Boolean deleteResult = redisTemplate.delete(tokenKey);

            if (Boolean.TRUE.equals(deleteResult)) {
                return getSuccess("退出登录成功！", null);
            } else {
                return getFail("退出登录失败，请稍后重试！");
            }

        } catch (Exception e) {
            return getFail("系统错误：" + e.getMessage());
        }
    }

    /**
     * 获取用户信息接口
     *
     * @param request HTTP请求对象，用于获取用户token
     * @return 响应结果，包含用户详细信息
     */
    @GetMapping("/getUserInfo")
    public ResponseVO<User> getUserInfo(HttpServletRequest request) {
        try {
            // 获取当前登录用户信息
            TokenUserDto tokenUserDto = getTokenUserDto(request);
            if (tokenUserDto == null) {
                return getFail("登录超时，请重新登录！");
            }

            // 查询用户详细信息
            User user = userDao.queryById(tokenUserDto.getUserId());
            if (user == null) {
                return getFail("用户不存在！");
            }

            // 清除敏感信息
            user.setPassword(null);
            user.setToken(null);

            return getSuccess("获取用户信息成功！", user);

        } catch (Exception e) {
            return getFail("系统错误：" + e.getMessage());
        }
    }

    /**
     * 清理头像路径接口 - 将绝对路径转换为相对路径
     * @param request HTTP请求对象
     * @return 响应结果
     */
    @PostMapping("/cleanAvatarPath")
    public ResponseVO<String> cleanAvatarPath(HttpServletRequest request) {
        try {
            TokenUserDto tokenUserDto = getTokenUserDto(request);
            if (tokenUserDto == null) {
                return getFail("登录超时，请重新登录！");
            }

            User currentUser = userDao.queryById(tokenUserDto.getUserId());
            if (currentUser == null) {
                return getFail("用户不存在！");
            }

            // 检查是否有头像路径需要清理
            String currentAvatar = currentUser.getTouXiang();
            if (StringUtils.isNotBlank(currentAvatar)) {
                // 如果不是D:/avatars/开头的路径，清空它
                if (!currentAvatar.startsWith("D:/avatars/")) {
                    User updateUser = new User();
                    updateUser.setUserId(currentUser.getUserId());
                    updateUser.setTouXiang(null); // 清空错误的路径
                    updateUser.setUpdatedAt(new Date());

                    int result = userDao.update(updateUser);
                    if (result > 0) {
                        return getSuccess("头像路径已清理，请重新上传头像！", null);
                    } else {
                        return getFail("清理失败，请稍后重试！");
                    }
                } else {
                    return getSuccess("头像路径正常，无需清理！", currentAvatar);
                }
            } else {
                return getSuccess("当前没有头像，无需清理！", null);
            }

        } catch (Exception e) {
            return getFail("系统错误：" + e.getMessage());
        }
    }

    /**
     * 获取头像访问URL接口
     * @param request HTTP请求对象
     * @return 头像访问URL
     */
    @GetMapping("/getAvatarUrl")
    public ResponseVO<String> getAvatarUrl(HttpServletRequest request) {
        try {
            TokenUserDto tokenUserDto = getTokenUserDto(request);
            if (tokenUserDto == null) {
                return getFail("登录超时，请重新登录！");
            }

            User user = userDao.queryById(tokenUserDto.getUserId());
            if (user == null) {
                return getFail("用户不存在！");
            }

            if (StringUtils.isBlank(user.getTouXiang())) {
                return getFail("用户未设置头像！");
            }

            // 构建前端可访问的URL
            String avatarPath = user.getTouXiang();
            if (avatarPath.startsWith("D:/avatars/")) {
                String filename = avatarPath.substring("D:/avatars/".length());
                String avatarUrl = "http://localhost:8080/avatars/" + filename;
                return getSuccess("获取头像URL成功！", avatarUrl);
            } else {
                return getFail("头像路径格式错误！");
            }

        } catch (Exception e) {
            return getFail("系统错误：" + e.getMessage());
        }
    }

}
